<template>
  <div>
    <v-data-table
      :headers="headers"
      :items="books"
      :options.sync="options"
      :page.sync="pager.page"
      :items-per-page.sync="pager.pageSize"
      :server-items-length="pager.total"
      :loading="loading"
      @update:items-per-page="handlePageSize"
      @update:page="handlePage"
    >
      <template v-slot:top>
        <v-toolbar flat color="white">
          <v-toolbar-title>Books</v-toolbar-title>
          <v-divider
            class="mx-4"
            inset
            vertical
          ></v-divider>
          <v-toolbar-items>
            <v-select
              :items="filterTypes"
              v-model="filteredType"
              label="Type"
              item-text="name"
              item-value="id"
              class="mt-4"
              @change="handleFilter"
            ></v-select>
            <v-text-field
              label="Name"
              v-model="filteredName"
              class="mt-4 ml-2"
              @keypress.enter="handleFilter"
            ></v-text-field>
            <v-btn-toggle
              v-model="borrowState"
              dense
              class="mt-4 ml-2"
              color="primary"
              multiple
              @change="handleFilter"
            >
              <v-btn>未借出</v-btn>
              <v-btn>已借出</v-btn>
            </v-btn-toggle>
            <v-btn text icon @click="handleFilter" class="ml-2">
              <v-icon>mdi-magnify</v-icon>
            </v-btn>
            <v-btn text icon @click="clearFilter">
              <v-icon>mdi-close</v-icon>
            </v-btn>
          </v-toolbar-items>
          <v-spacer></v-spacer>
          <v-dialog persistent v-model="dialog" max-width="640px">
            <template v-slot:activator="{ on }">
              <v-btn color="primary" dark class="mb-2" v-on="on">New Item</v-btn>
            </template>
            <v-card>
              <v-card-title>
                <span class="headline">{{ formTitle }}</span>
              </v-card-title>
              <v-card-text>
                <v-container>
                  <v-form ref="editForm" v-model="valid">
                    <v-row>
                      <v-text-field :rules="rules.code" v-model="editedItem.code" label="Code"></v-text-field>
                    </v-row>
                    <v-row>
                      <v-text-field :rules="rules.name" v-model="editedItem.name" label="Name"></v-text-field>
                    </v-row>
                    <v-row>
                      <v-col sm="6">
                        <v-text-field :rules="rules.author" v-model="editedItem.author" label="Author"></v-text-field>
                      </v-col>
                      <v-col sm="6">
                        <v-text-field :rules="rules.publish" v-model="editedItem.publish" label="Press"></v-text-field>
                      </v-col>
                    </v-row>
                    <v-row>
                      <v-menu
                        v-model="modalDatePicker"
                        :close-on-content-click="false"
                        :nudge-right="40"
                        transition="scale-transition"
                        offset-y
                        min-width="290px"
                      >
                        <template v-slot:activator="{ on }">
                          <v-text-field
                            v-model="editedItem.publishDate"
                            label="Publish Date"
                            prepend-icon="mdi-calendar"
                            readonly
                            v-on="on"
                          ></v-text-field>
                        </template>
                        <v-date-picker
                            v-model="editedItem.publishDate"
                            @input="modalDatePicker = false"
                        ></v-date-picker>
                      </v-menu>
                    </v-row>
                    <v-row>
                      <v-select
                        :items="bookTypes"
                        v-model="editedItem.type"
                        label="Type"
                        item-text="name"
                        item-value="id"
                        return-object
                        clearable
                      ></v-select>
                    </v-row>
                    <v-row>
                      <v-col sm="6">
                        <v-text-field
                          type="number"
                          v-model="editedItem.page"
                          label="Page"
                          :rules="rules.number"
                        ></v-text-field>
                      </v-col>
                      <v-col sm="6">
                        <v-text-field
                          type="number"
                          v-model="editedItem.price"
                          label="Price"
                          :rules="rules.number"
                        ></v-text-field>
                      </v-col>
                    </v-row>
                    <v-row>
                      <v-textarea label="Content" v-model="editedItem.content"></v-textarea>
                    </v-row>
                  </v-form>
                </v-container>
              </v-card-text>
              <v-card-actions>
                <v-spacer></v-spacer>
                <v-btn color="blue darken-1" text @click="hideDialog">Cancel</v-btn>
                <v-btn color="blue darken-1" text :disabled="!valid" :loading="loading" @click="handleSave">Save</v-btn>
              </v-card-actions>
            </v-card>
          </v-dialog>
        </v-toolbar>
      </template>
      <template v-slot:item.type="{item}">
        {{item.type ? item.type.name : ''}}
      </template>
      <template v-slot:item.borrowedUser="{item}">
        <v-chip v-if="item.borrowedUser">已被{{item.borrowedUser | nameOfUser}}借出</v-chip>
        <v-btn v-else color="primary" small rounded @click="$toasted.info('申请借阅《' + item.name + '》')">申请借阅</v-btn>
      </template>
      <template v-slot:item.publishDate="{item}">
        <span v-if="item.publishDate">{{item.publishDate | moment('YYYY-MM-DD')}}</span>
      </template>
      <template v-slot:item.createTime="{item}">
        {{item.createTime | moment('YYYY-MM-DD HH:mm:ss')}}
      </template>
      <template v-slot:item.updateTime="{item}">
        {{item.updateTime | moment('YYYY-MM-DD HH:mm:ss')}}
      </template>
      <template v-slot:item.action="{ item }">
        <v-icon
          small
          class="mr-2"
          @click="editItem(item.id)"
          :disabled="loading"
        >
          mdi-pencil
        </v-icon>
        <v-icon
          small
          @click="deleteItem(item.id)"
          :disabled="!!item.borrowedUser"
        >
          mdi-delete
        </v-icon>
      </template>
    </v-data-table>
    <v-dialog
      v-model="deleteDialog.visible"
      max-width="600px"
      persistent
    >
      <v-card>
        <v-card-title class="headline">Confirmation</v-card-title>
        <v-card-text>
          Are you sure to delete this item?
        </v-card-text>
        <v-card-actions>
          <v-spacer/>
          <v-btn text @click.stop="hideDeleteDialog">No</v-btn>
          <v-btn color="green darken-1" text @click="handleDelete" :loading="loading">Delete it anyway</v-btn>
        </v-card-actions>
      </v-card>
    </v-dialog>
  </div>
</template>
<style>
  tbody > tr:nth-child(odd) {
    background-color: #fafafa;
  }
</style>
<script>
  import {getBook, getBooks, deleteBook, updateBook, addBook} from "../../api/books";
  import {getBookTypes} from "../../api/booktype";

  export default {
    name: 'book',
    data: () => ({
      deleteDialog: {
        itemToDelete: null,
        visible: false
      },
      books: [],
      bookTypes: [],
      filterTypes: [{id: -1, name: 'All'}],
      filteredType: null,
      filteredName: '',
      borrowState: [0, 1],
      options: {},
      modalDatePicker: false,
      pager: {
        page: 1,
        pageSize: 20,
        total: 1,
        totalPages: 1,
      },
      rules: {
        code: [v => !!v || 'Code is required'],
        name: [v => !!v || 'Name is required'],
        author: [v => !!v || 'Author is required'],
        publish: [v => !!v || 'Press is required'],
        number: [
          v => !v || Math.floor(v).toString() === v.toString() || 'Field must be an integer',
          v => !v || v >= 0 || 'Field must be greater than zero'
        ],
      },
      valid: false,
      editedItem: {
        id: null,
        author: null,
        code: null,
        content: null,
        name: null,
        page: null,
        price: null,
        publish: null,
        publishDate: null,
        type: null,
        borrowedUser: null
      },
      formTitle: 'New Item',
      dialog: false,
      loading: true,
      headers: [
        { text: '代码', value: 'code', align: 'left', sortable: false },
        { text: '书名', value: 'name', align: 'left', sortable: false },
        { text: '作者', value: 'author', sortable: false },
        { text: '类别', value: 'type', sortable: false },
        { text: '出版社', value: 'publish', sortable: false },
        { text: '出版日期', value: 'publishDate', sortable: false },
        { text: '内容简介', value: 'content', sortable: false },
        { text: '页数', value: 'page', sortable: false },
        { text: '价格', value: 'price', sortable: false },
        { text: '借阅', value: 'borrowedUser', sortable: false },
        { text: '创建于', value: 'createTime', sortable: false },
        // { text: '更新于', value: 'updateTime', sortable: false },
        { text: '操作', value: 'action', sortable: false}
      ],
    }),
    methods: {
      clearFilter() {
        this.filteredType = -1;
        this.filteredName = '';
        this.borrowState = [0, 1];
        this.handleFilter();
      },
      handleFilter() {
        this.pager.page = 1;
        this.pager.total = 0;
        this.pager.totalPages = 0;
        this.loadBooks();
      },
      handlePage(page) {
        this.pager.page = page;
        this.loadBooks();
      },
      handlePageSize(size) {
        if (size === -1) {
          this.$toasted.error('Page size cannot be "All"');
          this.pager.pageSize = 15;
        }
        else {
          this.pager.pageSize = size;
          this.loadBooks();
        }
      },
      hideDialog() {
        this.loading = false;
        this.dialog = false;
        this.formTitle = 'New Item';
        Object.keys(this.editedItem).forEach(k => this.editedItem[k] = null);
        this.$refs['editForm'].reset();
      },
      hideDeleteDialog() {
        this.loading = false;
        this.deleteDialog.visible = false;
        this.deleteDialog.itemToDelete = null;
      },
      editItem(id) {
        this.loading = true;
        getBook(id).subscribe(res => {
          // console.log(res.data);
          if (res.data) {
            Object.keys(this.editedItem).forEach(k => this.editedItem[k] = res.data[k]);
            if (this.editedItem.publishDate)
              this.editedItem.publishDate = this.$moment(this.editedItem.publishDate).format('YYYY-MM-DD');
            this.formTitle = 'Edit';
            this.dialog = true;
          }
          else {
            this.$toasted.error('Cannot find book');
          }
          this.loading = false;
        }, err => {
          this.$toasted.error(err);
        })
      },
      deleteItem(id) {
        this.deleteDialog.itemToDelete = id;
        this.deleteDialog.visible = true;
      },
      handleSave() {
        if (this.editedItem.id) this.handleEdit();
        else this.handleAdd();
      },
      handleEdit() {
        this.loading = true;
        if (this.editedItem.id) {
          updateBook(this.editedItem).subscribe(res => {
            if (res.data) {
              this.$toasted.info('Book edited');
              this.loadBooks();
              this.hideDialog();
            }
            else this.$toasted.error('No response');
          }, err => {
            if (err.response.data) this.$toasted.error(err.response.data.message);
            else this.$toasted.error(err);
            this.loading = false;
          })
        }
      },
      handleAdd() {
        if (!this.editedItem.id) {
          this.loading = true;
          addBook(this.editedItem).subscribe(res => {
            if (res.data) {
              this.$toasted.info('Book added');
              this.loadBooks();
            }
            else this.$toasted.error('No response');
            this.hideDialog();
          }, err => {
            this.$toasted.error(err);
            this.hideDialog();
          })
        }
      },
      handleDelete() {
        this.loading = true;
        if (this.deleteDialog.itemToDelete) {
          deleteBook(this.deleteDialog.itemToDelete).subscribe(res => {
            if (res.status === 200) {
              this.$toasted.info('Book deleted');
              this.loadBooks();
            }
            else this.$toasted.error('No response');
            this.hideDeleteDialog();
          }, err => {
            this.loading = false;
            this.$toasted.error(err);
          })
        }
        else this.hideDeleteDialog();
      },
      loadBooks() {
        this.loading = true;
        const {page, pageSize} = this.pager;
        getBooks(page, pageSize, this.filteredType, this.filteredName, this.borrowState).subscribe(res => {
          // console.log(res);
          if (res.data) {
            this.books = res.data.data;
            const {page, pageSize, total, totalPages} = res.data;
            this.pager.page = page;
            this.pager.pageSize = pageSize;
            this.pager.total = total;
            this.pager.totalPages = totalPages;
          }
          this.loading = false;
        }, err => {
          this.$toasted.error(err);
          this.loading = false;
        })
      },
      loadBookTypes() {
        getBookTypes().subscribe(res => {
          if (res.data) {
            const {data} = res.data;
            this.filterTypes = [
              {
                id: -1,
                name: 'All'
              }, ...data
            ];
            this.bookTypes = [...data];
          }
        }, err => {
          this.$toasted.error(err);
        })
      },
    },
    mounted() {
      this.loadBooks();
      this.loadBookTypes();
    }
  }
</script>
